package com.common.core.results;

import brave.Span;
import brave.Tracer;
import brave.propagation.TraceContext;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.common.core.config.SpringApplicationContext;
import com.common.core.exception.code.BaseErrorCode;
import com.common.core.utils.CodeUtil;
import lombok.Data;
import org.springframework.context.ApplicationContext;

import java.io.Serializable;

/**
 * @auther WuJun.Zhang
 * @date 2022/3/21 下午2:35
 */
@Data
public abstract class Result implements Serializable {

    private static final long serialVersionUID = 1L;

    public Result() {
        ApplicationContext applicationContext = SpringApplicationContext.getContext();
        if (null != applicationContext) {
            Tracer tracer = applicationContext.getBean(Tracer.class);
            Span span = tracer.currentSpan();
            if (null != span) {
                TraceContext traceContext = span.context();
                if (null != traceContext) {
                    this.traceId = traceContext.traceIdString();
                }
            } else {
                this.traceId = CodeUtil.getNonceStr(16);
            }
        }
    }

    @JSONField(ordinal = 1)
    private String traceId;

    @JSONField(ordinal = 2)
    private boolean success;

    @JSONField(ordinal = 3)
    private int errNum;

    @JSONField(ordinal = 4)
    private String errMsg;

    protected static VoidResult voidResult() {
        VoidResult result = new VoidResult();
        result.setSuccess(true);
        BaseErrorCode code = BaseErrorCode.SUCCESS;
        result.setErrNum(code.getErrNum());
        result.setErrMsg(code.getErrMsg());
        return result;
    }

    protected static <T> SingleResult<T> singleResult(T payload) {
        SingleResult<T> result = new SingleResult<>();
        result.setSuccess(true);
        BaseErrorCode code = BaseErrorCode.SUCCESS;
        result.setErrNum(code.getErrNum());
        result.setErrMsg(code.getErrMsg());
        result.setPayload(payload);
        return result;
    }

    protected static <T> MultiResult<T> multiResult(MultiResult.Multi<T> payload) {
        MultiResult<T> result = new MultiResult<>();
        result.setSuccess(true);
        BaseErrorCode code = BaseErrorCode.SUCCESS;
        result.setErrNum(code.getErrNum());
        result.setErrMsg(code.getErrMsg());
        result.setPayload(payload);
        return result;
    }

    protected static <T> PageResult<T> pageResult(PageResult.Page<T> payload) {
        PageResult<T> result = new PageResult<>();
        result.setSuccess(true);
        BaseErrorCode code = BaseErrorCode.SUCCESS;
        result.setErrNum(code.getErrNum());
        result.setErrMsg(code.getErrMsg());
        result.setPayload(payload);
        return result;
    }

    @Override
    public String toString() {
        return JSON.toJSONString(this, SerializerFeature.WriteMapNullValue);
    }
}
